/**
 *
 */
package com.lb.uts.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 不同概率抽奖工具包
 *  这里用作权重的实现
 * @author liuxc
 * @since 2018年1月18日
 */
public class LotteryUtil {

    private static final Logger logger = LoggerFactory.getLogger(LotteryUtil.class);

    /**
     * 抽奖
     *
     * @param orignalRates 原始的概率列表，保证顺序和实际物品对应
     * @return 物品的索引
     */
    public static int lottery(List<Double> orignalRates) {

        int index = doLottery(orignalRates);
        int n = 0;
        //概率为0的重新抽奖
        while (Double.compare(0.00d, orignalRates.get(index)) == 0) {
            index = doLottery(orignalRates);
            logger.error("超豆抽奖抽到概率为零的奖品");
            if (++n == 10 && Double.compare(0.00d, orignalRates.get(index)) == 0) throw new RuntimeException("奖励配置不对");
        }
        return index;
    }

    public static int doLottery(List<Double> orignalRates) {
        if (orignalRates == null || orignalRates.isEmpty()) {
            return -1;
        }

        int size = orignalRates.size();

        // 计算总概率，这样可以保证不一定总概率是1
        double sumRate = 0d;
        for (double rate : orignalRates) {
            sumRate += rate;
        }

        // 计算每个物品在总概率的基础下的概率情况
        List<Double> sortOrignalRates = new ArrayList<Double>(size);
        Double tempSumRate = 0d;
        for (double rate : orignalRates) {
            tempSumRate += rate;
            sortOrignalRates.add(tempSumRate / sumRate);
        }

        // 根据区块值来获取抽取到的物品索引
        double nextDouble = Math.random();
        sortOrignalRates.add(nextDouble);
        Collections.sort(sortOrignalRates);
        return sortOrignalRates.indexOf(nextDouble);
    }

    public static void main(String[] args) {
        List<Double> orignalRates = new ArrayList<Double>();
//        orignalRates.add(0.3);
//        orignalRates.add(0.05);
//        orignalRates.add(0.09);
//        orignalRates.add(0.0);
//        orignalRates.add(0.05);
//        orignalRates.add(0.3);
//        orignalRates.add(0.2);
//        orignalRates.add(0.01);
        orignalRates.add(0d);
        orignalRates.add(0d);
        orignalRates.add(0d);
        orignalRates.add(0d);
        orignalRates.add(0d);
        orignalRates.add(0d);
        orignalRates.add(0d);
        orignalRates.add(0.01);
        for (int i = 0; i < 1; i++) {
            System.err.println(lottery(orignalRates));
        }
    }
}
